import {PluginCommand} from "./PluginCommand";
import {
  Axis, Direction,Point
} from "../../nodeApp/static/lib/crowncad-plugin-sdk-0.0.1";
import {symmetryPoint} from "../util/Common";
import {ElementType} from "../modeling/TypeDefine";
import {sketchCoordinateSystem} from "../views/WorkAreaComponents/GearDesign/SketchCoordinateSystem";

class GearDesignCommand extends PluginCommand {
  constructor() {
    super();
    this.hideEntityIds = [];
  }

  init(maxWidth = 500, minWidth = 500, maxHeight = 550, cb = () => {}) {
    super.init(maxWidth, minWidth, maxHeight, result => {
      cb();
      //关闭右侧窗口
      this.setPluginRightNavigation();
    })
  }

  //  创建柱正齿轮
  async createSpurGear(spurGearParams, cb = () => {}) {
    this.hideEntityIds = [];
    await this.command.execute(true, "print(1);");
    //创建齿顶圆草图
    let sketchFeature1 = await this.createAddendumSketch(spurGearParams.ra);
    //创建渐开线草图
    let sketchFeature2 = await this.createHelixCutSketch(spurGearParams);
    // 创建草图圆角
    await this.createFillet(sketchFeature2, spurGearParams.teethFilterR, spurGearParams.rf);
    // 创建拉伸体
    let extrudeFeature = await this.extrudeAddendum(sketchFeature1, spurGearParams.teethWidth);
    // 创建切除体
    let cutFeature = await this.extrudeCutSpurGear(sketchFeature2, extrudeFeature, spurGearParams.teethWidth);
    // 创建圆周阵列
    await this.circularPattern(cutFeature, spurGearParams.teethNumber);
    // 隐藏基准面、草图等特征
    await this.hideEntities();
    cb();
  }

  //  创建柱斜齿轮
  async createHelixGear(helixGearParams, cb = () => {}) {
    this.hideEntityIds = [];
    //清空文档中的数据
    await this.command.execute(true, "print(1);");
    //创建齿顶圆草图
    let sketchFeature1 = await this.createAddendumSketch(helixGearParams.ra);  // 创建草图
    //创建渐开线草图
    let sketchFeature2 = await this.createHelixCutSketch(helixGearParams);
    // 创建草图圆角
    await this.createFillet(sketchFeature2, helixGearParams.teethFilterR, helixGearParams.rf);
    // 创建拉伸体
    let extrudeFeature = await this.extrudeAddendum(sketchFeature1, helixGearParams.teethWidth);
    // 创建草图基准面
    let sketchDatumFeature = await this.creatLoftSketchDatum(helixGearParams.teethWidth);
    // 创建放样草图
    let loftSketchFeature = await this.creatLoftSketch(sketchDatumFeature, sketchFeature2);
    // 编辑放样草图
    await this.editLoftSketch(loftSketchFeature, helixGearParams);
    // 创建放样切除引导线
    let guideLineFeature = await this.createLoftCutGuideLine(sketchFeature2, loftSketchFeature);
    // 放样凸台
    let loftFeature = await this.loftHelixGear(sketchFeature2, loftSketchFeature, guideLineFeature, helixGearParams.helixDirection);
    // 创建放样凸台圆周阵列
    let circularPatternFeature = await this.loftCircularPattern(loftFeature, helixGearParams.teethNumber);
    // 布尔减创建圆柱斜齿轮
    await this.booleanSubtractLoft(extrudeFeature, loftFeature, circularPatternFeature);
    // 隐藏基准面、草图等特征
    await this.hideEntities();
    cb();
  }

  //隐藏基准面、草图等特征对象
  async hideEntities() {
    //获取基准面的ID
    let featureNames = ["前视基准面", "右视基准面", "上视基准面"];
    let features = await this.query.getEntitiesByFeatureNames(featureNames);
    let entities = features?.data?.entities;
    if (!entities || entities?.length === 0){
      return;
    }
    entities.forEach(entity => {
      this.hideEntityIds.push(entity.id);
    })
    if (this.hideEntityIds.length > 0) {
      let common = this.command.common;
      await common.setEntityVisibleIncrement({entityIds: this.hideEntityIds, status: 0});
    }
  }

  // 创建齿顶圆草图
  async createAddendumSketch(ra) {
    let sketch = this.command.sketch;
    sketch.createSketch({sketchName: '', datumId: 8});
    sketch.createCircle({centerPoint: new Point(0, 0), circlePoint: new Point(ra, 0)});
    sketch.exitSketch();
    let res = await this.command.executeIncrementCommand(this.command.commandScript);
    this.command.clearCommand();
    let currentFeature = res?.data?.modelData?.currentFeature;
    if (currentFeature && currentFeature.length > 0) {
      let sketchFeature = {
        id: currentFeature[0]?.id,
        name: currentFeature[0]?.name,
      }
      return sketchFeature;
    }
  }

  // 创建柱斜齿轮拉伸切除草图
  async createHelixCutSketch(gearParams) {
    let sketch = this.command.sketch;
    sketch.createSketch({sketchName: '', datumId: 8});
    const angle = Math.PI / 3;
    const hAngle = gearParams.helixAngle / 2;

    /*
    绘制两侧渐开线：
    获取右侧渐开线与分度圆交点 Q
    通过齿距弦长计算 OQ 与对称轴之间的角度 θ，得到 Q 在对称轴上的投影点 M
    以 OM 为对称轴，得到左侧渐开线
    */
    const QPoint = this.getIntersectionPointInInvolute(0, angle, gearParams.rb, gearParams.rp);
    const theta = Math.PI / (2 * gearParams.teethNumber);
    const mX = QPoint.x * Math.cos(theta) - QPoint.y * Math.sin(theta);
    const mY = QPoint.x * Math.sin(theta) + QPoint.y * Math.cos(theta);
    const MPoint = new THREE.Vector3(mX, mY);
    const OPoint = new THREE.Vector3(0, 0);

    // 齿根圆关键点与其对称点
    let pointF = this.getPoint({x: 0, y: gearParams.rf});
    let pointFS = this.getPoint(symmetryPoint(new THREE.Vector3(0, gearParams.rf), OPoint, MPoint));

    // 齿顶圆与右侧渐开线的交点P, 交点处的角度值, 以及其对称点PS
    let intersectionPointAndAngle = this.getIntersectionPointAndAngleInInvolute(0, angle, gearParams.rb, gearParams.ra);
    let intersectionPointAngle = intersectionPointAndAngle.angle;
    let pointP = this.getPoint({x: intersectionPointAndAngle.x, y: intersectionPointAndAngle.y});
    let pointPS = this.getPoint(symmetryPoint(new THREE.Vector3(intersectionPointAndAngle.x, intersectionPointAndAngle.y), OPoint, MPoint));  // 对称点

    // 绘制渐开线
    const involuteRightPoints = [];
    const involuteLeftPoints = [];
    const increment = 0.05;
    if (gearParams.rb > gearParams.rf) {
      for (let i = 0; i < intersectionPointAngle; i += increment) {
        const x = gearParams.rb * (Math.sin(i) - i * Math.cos(i));
        const y = gearParams.rb * (Math.cos(i) + i * Math.sin(i));
        involuteRightPoints.push(this.getPoint({x, y}));
        const symPoint = symmetryPoint(new THREE.Vector3(x, y), OPoint, MPoint);  // 对称点
        involuteLeftPoints.push(this.getPoint(symPoint));
      }
      // 添加与齿顶圆的交点
      involuteRightPoints.push(pointP);
      involuteLeftPoints.push(pointPS);
      // 渐开线最后一个点为与齿顶圆交点外一点的点
      let lastPointAngle = intersectionPointAngle + 0.03 + hAngle;
      const x = gearParams.rb * (Math.sin(lastPointAngle) - lastPointAngle * Math.cos(lastPointAngle));
      const y = gearParams.rb * (Math.cos(lastPointAngle) + lastPointAngle * Math.sin(lastPointAngle));
      involuteRightPoints.push(this.getPoint({x, y}));
      const symPoint = symmetryPoint(new THREE.Vector3(x, y), OPoint, MPoint);  // 对称点
      involuteLeftPoints.push(this.getPoint(symPoint));
    } else {  // 齿根圆半径大于基圆半径，以齿根圆与渐开线交点为起点，绘制渐开线
      const interPoint = this.getIntersectionPointInInvolute(0, angle, gearParams.rb, gearParams.rf);
      pointF = this.getPoint(interPoint);
      pointFS = this.getPoint(symmetryPoint(new THREE.Vector3(interPoint.x, interPoint.y), OPoint, MPoint));
      involuteRightPoints.push(pointF);
      involuteLeftPoints.push(pointFS);
      for (let i = 0; i < angle; i += increment) {
        const x = gearParams.rb * (Math.sin(i) - i * Math.cos(i));
        const y = gearParams.rb * (Math.cos(i) + i * Math.sin(i));
        if (Math.sqrt(x * x + y * y) > gearParams.rf) {
          involuteRightPoints.push(this.getPoint({x, y}));
          const symPoint = symmetryPoint(new THREE.Vector3(x, y), OPoint, MPoint);
          involuteLeftPoints.push(this.getPoint(symPoint));
        }
      }
      // 渐开线最后一个点为与齿顶圆交点外一点的点
      let lastPointAngle = angle + 0.03 + hAngle;
      const x = gearParams.rb * (Math.sin(lastPointAngle) - lastPointAngle * Math.cos(lastPointAngle));
      const y = gearParams.rb * (Math.cos(lastPointAngle) + lastPointAngle * Math.sin(lastPointAngle));
      involuteRightPoints.push(this.getPoint({x, y}));
      const symPoint = symmetryPoint(new THREE.Vector3(x, y), OPoint, MPoint);  // 对称点
      involuteLeftPoints.push(this.getPoint(symPoint));
    }

    sketch.createIntpCurve({pickPoints: involuteRightPoints});
    sketch.createIntpCurve({pickPoints: involuteLeftPoints});

    // 两侧渐开线上顶点连线
    sketch.createArcByCenter({
      centerPoint: new Point(0, 0),
      startPoint: new Point(involuteRightPoints[involuteLeftPoints.length - 1].x, involuteRightPoints[involuteLeftPoints.length - 1].y),
      endPoint: new Point(involuteLeftPoints[involuteLeftPoints.length - 1].x, involuteLeftPoints[involuteLeftPoints.length - 1].y)
    });

    // 齿根圆
    sketch.createArcByCenter({
      centerPoint: new Point(0, 0),
      startPoint: pointF,
      endPoint: pointFS
    });

    const delta = Math.sqrt((involuteRightPoints[0].x - pointF.x) * (involuteRightPoints[0].x - pointF.x) +
      (involuteRightPoints[0].y - pointF.y) * (involuteRightPoints[0].y - pointF.y));
    if (delta > gearParams.teethFilterR) {
      // 渐开线与圆角连线
      sketch.createSketchLine({
        startPoint: new Point(involuteRightPoints[0].x, involuteRightPoints[0].y),
        endPoint: pointF
      });
      sketch.createSketchLine({
        startPoint: new Point(involuteLeftPoints[0].x, involuteLeftPoints[0].y),
        endPoint: pointFS
      });
    }
    sketch.exitSketch();
    let res = await this.command.executeIncrementCommand(this.command.commandScript);
    this.command.clearCommand();
    let currentFeature = res?.data?.modelData?.currentFeature;
    if (currentFeature && currentFeature.length > 0) {
      let sketchFeature = {
        id: currentFeature[0]?.id,
        name: currentFeature[0]?.name,
        distance: delta,
      }
      return sketchFeature;
    }
  }

  // 齿根圆圆角
  async createFillet(sketchFeature, rho, rf) {
    if (!sketchFeature || !this.query || !this.command.sketch) {
      return;
    }
    let dis = sketchFeature.distance;
    if (!dis) {
      return;
    }
    let elements = await this.getElementsByFeature(sketchFeature);
    let arcF, rInv, lInv;
    let tempElement;
    elements?.forEach(element => {
      if (element.params.type === 12 && Math.abs(element.params.startPoint[1] - rf) < 0.001) {
        arcF = element.id;
      }
      if (element.params.type === 10 && dis > rho) {
        if (element.params.startPoint[0] === 0) {
          rInv = element.id;
        } else if (element.params.startPoint[0] < 0 && element.params.endPoint[0] < 0) {
          lInv = element.id;
        }
      } else if (dis <= rho && element.params.type === 15) {
        if (tempElement) {
          if (element.params.startPoint[0] > tempElement.params.startPoint[0]) {
            rInv = element.id;
            lInv = tempElement.id;
          } else {
            rInv = tempElement.id;
            lInv = element.id;
          }
        }
        tempElement = element;
      }
    });
    if (arcF && rInv && lInv) {
      let sketch = this.command.sketch;
      sketch.editSketch({sketchName: sketchFeature.name});
      sketch.createFilletCurve({curveId1: arcF, curveId2: rInv, radius: rho, type1: 2, type2: 2});
      sketch.createFilletCurve({curveId1: arcF, curveId2: lInv, radius: rho, type1: 2, type2: 2});
      sketch.exitEditSketch({sketchName: sketchFeature.name});
      await this.command.executeIncrementCommand(this.command.commandScript);
      this.command.clearCommand();
    }
  }

  //通过featureId获取实体
  async getEntitiesByFeature(feature) {
    let res = await this.query.getEntitiesByFeatureIds([feature?.id]);
    let entities = res?.data?.entities;
    return entities?.length > 0 ? entities : null;
  }
  //通过featureId获取元素
  async getElementsByFeature(feature){
    let res = await this.query.getElementsByFeatureId(feature?.id);
    let elements = res?.data?.elements;
    return elements;
  }
  //执行增量命令并返回当前特征对象
  async executeIncrementCommand() {
    let res = await this.command.executeIncrementCommand(this.command.commandScript);
    this.command.clearCommand();
    let currentFeature = res?.data?.modelData?.currentFeature;
    if (currentFeature && currentFeature.length > 0) {
      let feature = {
        id: currentFeature[0]?.id,
        name: currentFeature[0]?.name,
      }
      return feature;
    }
  }

  // 获取基圆在 [startAngle, endAngle] 之间渐开线与目标圆的交点
  getIntersectionPointInInvolute(startAngle, endAngle, baseR, targetR) {
    const midAngle = (startAngle + endAngle) / 2;
    const x = baseR * (Math.sin(midAngle) - midAngle * Math.cos(midAngle));
    const y = baseR * (Math.cos(midAngle) + midAngle * Math.sin(midAngle));
    const delta = Math.sqrt(x * x + y * y) - targetR;
    if (Math.abs(delta) < 0.001) {
      return {x, y};
    }
    let diff = endAngle - startAngle;
    if (delta > 0 && diff > 0.000001) {  // 二分中点在目标圆外部
      return this.getIntersectionPointInInvolute(startAngle, midAngle, baseR, targetR);
    } else if (delta < 0 && diff > 0.000001) {  // 二分中点在目标圆内部
      return this.getIntersectionPointInInvolute(midAngle, endAngle, baseR, targetR);
    } else if (delta < 0 && diff < 0.000001) {  // 二分中点在目标圆内部
      return this.getIntersectionPointInInvolute(midAngle, endAngle + 0.1, baseR, targetR);
    }
  }

  // 获取基圆在 [startAngle, endAngle] 之间渐开线与目标圆的交点
  getIntersectionPointAndAngleInInvolute(startAngle, endAngle, baseR, targetR) {
    const midAngle = (startAngle + endAngle) / 2;
    const x = baseR * (Math.sin(midAngle) - midAngle * Math.cos(midAngle));
    const y = baseR * (Math.cos(midAngle) + midAngle * Math.sin(midAngle));
    const delta = Math.sqrt(x * x + y * y) - targetR;
    if (Math.abs(delta) < 0.001) {
      let retValue = {
        x: x,
        y: y,
        angle: midAngle
      }
      return retValue;
    }
    let diff = endAngle - startAngle;
    if (delta > 0 && diff > 0.000001) {  // 二分中点在目标圆外部
      return this.getIntersectionPointAndAngleInInvolute(startAngle, midAngle, baseR, targetR);
    } else if (delta < 0 && diff > 0.000001) {  // 二分中点在目标圆内部
      return this.getIntersectionPointAndAngleInInvolute(midAngle, endAngle, baseR, targetR);
    } else if (delta < 0 && diff < 0.000001) {  // 二分中点在目标圆内部
      return this.getIntersectionPointAndAngleInInvolute(midAngle, endAngle + 0.1, baseR, targetR);
    }
  }

  // 创建齿顶圆拉伸体
  async extrudeAddendum(sketchFeature, teethWidth) {
    if (this.query && sketchFeature) {
      let entities = await this.getEntitiesByFeature(sketchFeature);
      if (entities && entities.length > 0) {
        // this.command.solid.extrude({
        //   sketch: entities[0]?.id,
        //   height1: teethWidth + ''
        // }, '');
        let res = await this.command.solid.extrudeIncrement({
          sketch: entities[0]?.id,
          height1: teethWidth + ''
        }, '');
        let currentFeature = res?.data?.modelData?.currentFeature;
        if (currentFeature && currentFeature.length > 0) {
          let feature = {
            id: currentFeature[0]?.id,
            name: currentFeature[0]?.name,
          }
          return feature;
        }
      }
    }
  }

  // 创建柱正齿轮切除体
  async extrudeCutSpurGear(sketchFeature, extrudeFeature, teethWidth) {
    let solid = this.command?.solid;
    if (!solid || !sketchFeature || !extrudeFeature) {
      return;
    }
    let sketchEntities = await this.getEntitiesByFeature(sketchFeature);
    if (sketchEntities && sketchEntities.length > 0) {
      let extrudeEntities = await this.getEntitiesByFeature(extrudeFeature);
      if (extrudeEntities && extrudeEntities.length > 0) {
        let res = await solid.extrudeCutIncrement({
          sketch: sketchEntities[0]?.id, height1: teethWidth + '', cutSolids: [extrudeEntities[0]?.id]
        }, '');
        let currentFeature = res?.data?.modelData?.currentFeature;
        if (currentFeature && currentFeature.length > 0) {
          let feature = {
            id: currentFeature[0]?.id,
            name: currentFeature[0]?.name,
          }
          return feature;
        }
      }
    }
  }

  // 创建圆周阵列
  async circularPattern(cutFeature, teethNumber) {
    if (cutFeature) {
      const axis = new Axis();
      axis.setPoint(new Point(0, 0, 0), new Point(0, 0, 10));
      let res = await this.command.solid.circularPatternIncrement({
        baseType: 1, features: [cutFeature?.id], axis: axis, angle1: 360, instanceNum1: teethNumber,
      }, '');
      let currentFeature = res?.data?.modelData?.currentFeature;
      if (currentFeature && currentFeature.length > 0) {
        let feature = {
          id: currentFeature[0]?.id,
          name: currentFeature[0]?.name,
        }
        return feature;
      }
    }
  }

  // 处理点坐标的误差
  getPoint(point) {
    const x = Math.abs(point.x) < 1e-10 ? 0 : point.x;
    const y = Math.abs(point.y) < 1e-10 ? 0 : point.y;
    return new Point(x, y);
  }

  // 创建切除放样草图基准平面
  async creatLoftSketchDatum(dis) {
    if (this.command.datum) {
      let res = await this.command.datum.createPlaneByDistanceIncrement({
        planeId: 8,
        invertNormal: 0,
        paralDis: dis,
        reverse: 0,
      }, '');
      let currentFeature = res?.data?.modelData?.currentFeature;
      if (currentFeature && currentFeature.length > 0) {
        let feature = {
          id: currentFeature[0]?.id,
          name: currentFeature[0]?.name,
        }
        return feature;
      }
    }
  }

  // 创建放样草图
  async creatLoftSketch(sketchDatumFeature, sketchFeature) {
    let sketch = this.command.sketch;
    if (!sketch || !sketchDatumFeature || !sketchFeature) {
      return;
    }
    let datumEntities = await this.getEntitiesByFeature(sketchDatumFeature);
    if (datumEntities && datumEntities.length > 0) {
      let sketchElements = await this.getElementsByFeature(sketchFeature);
      let edgeIds = [];
      sketchElements?.forEach(element => {
        if (element.type === 8) {
          edgeIds.push(element.id);
        }
      })
      let entityId = datumEntities[0]?.id;
      this.hideEntityIds.push(entityId);
      sketch.createSketch({sketchName: '', datumId: entityId});
      sketch.convertEdge({edgeIds: edgeIds});
      sketch.exitSketch();
      let feature = await this.executeIncrementCommand();
      return feature;
    }
  }

  // 编辑放样草图
  async editLoftSketch(loftSketchFeature, gearParams) {
    if (!loftSketchFeature) {
      return;
    }
    let helixDirection = gearParams.helixDirection;
    let helixAngle = gearParams.helixAngle;
    let helixWidth = gearParams.teethWidth;
    let helixRa = gearParams.ra;
    let rotateArcAngle = 2 * Math.asin(0.5 * helixWidth * Math.tan(helixAngle) / helixRa);
    let rotateAngle = 0.0;  // 草图旋转角度值
    if (helixDirection === 1) { // 左旋
      rotateAngle -= rotateArcAngle / Math.PI * 180;
    } else if (helixDirection === 2) { // 右旋
      rotateAngle = rotateArcAngle / Math.PI * 180;
    }
    let elementIds = [];
    let elements = await this.getElementsByFeature(loftSketchFeature);
    elements.forEach(element => {
      if (element.type === 8) {
        elementIds.push(element.id);
      }
    });
    let sketch = this.command.sketch;
    sketch.editSketch({sketchName: loftSketchFeature.name});
    sketch.rotateElements({elementIds: elementIds, circlePoint: new Point(0, 0), angle: rotateAngle});
    sketch.exitEditSketch({sketchName: loftSketchFeature.name});
    await this.command.executeIncrementCommand(this.command.commandScript);
    this.command.clearCommand();
  }

  // 放样创建柱斜齿轮切除体
  async loftHelixGear(sketchFeature, loftSketchFeature, guideLineFeature, helixDirection) {
    if (!sketchFeature || !loftSketchFeature || !guideLineFeature) {
      return;
    }
    let sketchs = [];
    let sketchEntities = await this.getEntitiesByFeature(sketchFeature);
    if (sketchEntities) {
      let loftSketchEntities = await this.getEntitiesByFeature(loftSketchFeature);
      if (loftSketchEntities) {
        if (helixDirection === 1) {
          sketchs.push(sketchEntities[0]?.id);
          sketchs.push(loftSketchEntities[0]?.id);
        } else if (helixDirection === 2) {
          sketchs.push(loftSketchEntities[0]?.id);
          sketchs.push(sketchEntities[0]?.id);
        }
        let guideEntities = await this.getEntitiesByFeature(guideLineFeature);
        if (guideEntities) {
          let guideEntityId = guideEntities[0]?.id;
          this.hideEntityIds.push(guideEntityId);
          let res = await this.command.solid.loftIncrement({
            sketchs: sketchs,
            hasGuideCurve: 1,
            guideCurves: [guideEntityId],
          }, '');
          let currentFeature = res?.data?.modelData?.currentFeature;
          if (currentFeature && currentFeature.length > 0) {
            let feature = {
              id: currentFeature[0]?.id,
              name: currentFeature[0]?.name,
            }
            return feature;
          }
        }
      }
    }
  }

  // 圆周阵列放样切除体
  async loftCircularPattern(loftFeature, teethNumber) {
    if (!loftFeature) {
      return;
    }
    const axis = new Axis();
    axis.setPoint(new Point(0, 0, 0), new Point(0, 0, 10));
    let entities = await this.getEntitiesByFeature(loftFeature);
    if (entities) {
      let res = await this.command.solid.circularPatternIncrement({
        baseType: 0, body: entities[0]?.id, axis: axis, angle1: 360, instanceNum1: teethNumber,
      }, '');
      let currentFeature = res?.data?.modelData?.currentFeature;
      if (currentFeature && currentFeature.length > 0) {
        let feature = {
          id: currentFeature[0]?.id,
          name: currentFeature[0]?.name,
        }
        return feature;
      }
    }
  }

  // 使用布尔运算减创建柱斜齿轮
  async booleanSubtractLoft(extrudeFeature, loftFeature, circularPatternFeature) {
    if (!extrudeFeature || !loftFeature || !circularPatternFeature) {
      return;
    }
    let extrudeEntities = await this.getEntitiesByFeature(extrudeFeature);
    let loftEntities = await this.getEntitiesByFeature(loftFeature);
    let circularPatternRes = await this.toolQuery.getEntitiesByFeatureId(circularPatternFeature?.id);
    let circularPatternEntities = circularPatternRes?.data?.entities;
    let cutSolidIds = [], targetSolidId;
    if (extrudeEntities && loftEntities && circularPatternEntities) {
      cutSolidIds.push(loftEntities[0]?.id);
      circularPatternEntities.forEach(entity => {
        cutSolidIds.push(entity.id);
      });
      targetSolidId = extrudeEntities[0]?.id;
      await this.command.solid.booleanSubtractIncrement({
        entityBs: cutSolidIds,
        entityA: targetSolidId,
        keep: 0
      }, '');
    }
  }

  async createLoftCutGuideLine(sketchFeature, loftSketchFeature) {
    if (!sketchFeature || !loftSketchFeature) {
      return;
    }
    let pickPoints = [];
    let loftElements = await this.getElementsByFeature(loftSketchFeature);
    loftElements?.forEach(element => {
      if (element.params.type === 16 && pickPoints.length === 0) {
        let pnt = new Point(element.params.startPoint[0], element.params.startPoint[1], element.params.startPoint[2]);
        pnt = this.infinitesimal(pnt);
        pickPoints.push(pnt);
      }
    });
    if (pickPoints.length === 1) {
      let sketchElements = await this.getElementsByFeature(sketchFeature);
      sketchElements?.forEach(sketchElement => {
        if (sketchElement.params.type === 15 && pickPoints.length === 1) {
          let x = sketchElement.params.startPoint[0];
          if (Math.abs(x) < 0.00001) {
            x = 0;
          }
          let y = sketchElement.params.startPoint[1];
          if (Math.abs(y) < 0.00001) {
            y = 0;
          }
          let z = sketchElement.params.startPoint[2];
          if (Math.abs(z) < 0.00001) {
            z = 0;
          }
          let pnt = this.infinitesimal(new Point(x, y, z));
          pickPoints.push(pnt);
        }
      });
    }
    //创建引导线
    if (pickPoints.length === 2) {
      let res = await this.command.curve.createCurveByInterpolationPointsIncrement({pickPnts: pickPoints}, '引导线');
      let currentFeature = res?.data?.modelData?.currentFeature;
      if (currentFeature && currentFeature.length > 0) {
        let feature = {
          id: currentFeature[0]?.id,
          name: currentFeature[0]?.name,
        }
        return feature;
      }
    }
  }

  //创建圆锥直齿轮
  async createConicalSpurGear(gearParams, cb = () => {
  }) {
    this.hideEntityIds = [];
    await this.command.execute(true, "print(1);");
    //创建圆锥
    await this.createCones(gearParams);
    //创建基准面和草图
    await this.createDatumAndSketch(gearParams);
    //创建引导线
    await this.createGuideLine();
    //创建放样凸台
    await this.createLoft('草图1', '草图2');
    //创建圆周阵列
    let circularPatternFeature = await this.createCircularPattern(gearParams.teethNumber);
    //布尔减运算
    await this.boolSub(circularPatternFeature);
    //隐藏基准面/草图/引导线等
    await this.hideEntities();
    cb();
  }
  //创建基准面和草图
  async createDatumAndSketch(gearParams) {
    const datum = this.command.datum;
    const sketch = this.command.sketch;
    /**
     * 大圆基准面及草图创建
     */
    //创建大圆基准面
    let datumFeature;
    if (gearParams.helixDirection != 0) {
      //锥直齿轮的方向及坐标点
      let lineDir = new THREE.Vector3(-1, 1 / Math.tan(gearParams.delta), 0).normalize();
      let linePoint = new THREE.Vector3(0, 0, 0);
      let point = new THREE.Vector3(0, 0, 0);
      let newPnt1 = this.getLineRevolvePoint(lineDir, linePoint, point, 90);
      let newDir1 = this.getLineRevolvePoint(lineDir, linePoint, new THREE.Vector3(0, 0, 1), 90).sub(this.getLineRevolvePoint(lineDir, linePoint, new THREE.Vector3(), 90));
      //按螺旋角度进行旋转后的基准面的法向及坐标点
      let newPnt2 = this.getLineRevolvePoint(new THREE.Vector3(1,0,0), new THREE.Vector3(), newPnt1, gearParams.helixAngle);
      let originDir = this.getLineRevolvePoint(new THREE.Vector3(1,0,0), new THREE.Vector3(), new THREE.Vector3(), gearParams.helixAngle);
      let newDir2 = this.getLineRevolvePoint(new THREE.Vector3(1,0,0), new THREE.Vector3(), newDir1, gearParams.helixAngle).sub(originDir);
      let axis = new Axis();
      axis.setPoint(new Point(), new Point(newDir2.x, newDir2.y, newDir2.z));
      let res = await datum.createPlaneByPointNormalIncrement({
        planeAxis: axis,
        planePnt: new Point(newPnt2.x, newPnt2.y),
      }, "基准面1");
      let currentFeature = res?.data?.modelData?.currentFeature;
      if (currentFeature && currentFeature.length > 0) {
        let feature = {
          id: currentFeature[0]?.id,
          name: currentFeature[0]?.name,
        }
        datumFeature = feature;
      }
    } else {
      const axis = new Axis();
      let point1 = new Point(0, 0, 0);
      let point2 = new Point(-1, 1 / Math.tan(gearParams.delta), 0);
      let axisAngle = 90;
      axis.setPoint(point1, point2);
      let res = await datum.createPlaneByPlaneAngleIncrement({
        planeId: 8,
        additionalAxis: axis,
        axisAngle: axisAngle,
      }, "基准面1");
      let currentFeature = res?.data?.modelData?.currentFeature;
      if (currentFeature && currentFeature.length > 0) {
        let feature = {
          id: currentFeature[0]?.id,
          name: currentFeature[0]?.name,
        }
        datumFeature = feature;
      }
    }

    //获取基准面1的ID
    let entities = await this.getEntitiesByFeature(datumFeature);
    if (entities?.length === 0) {
      return;
    }
    let datumId1 = entities?.[0].id;
    this.hideEntityIds.push(datumId1);
    //创建大圆草图
    gearParams.ra = gearParams.ra1;
    gearParams.rb = gearParams.rb1;
    gearParams.rf = gearParams.rf1;
    gearParams.rp = gearParams.rp1;
    let distance1 = await this.createGearSketch("草图1", datumId1, gearParams);
    // let distance = this.createHelixCutSketch(sketch, "草图1", datumId1, gearParams);
    //旋转一个角度
    await this.moveRotateElements("草图1", gearParams);
    // 做倒圆角
    // await this.createFilletCorner(distance1, "草图1");
    // // await this.command.execute();
    // // this.command.clearCommand();
    /**
     * 小圆基准面及草图创建
     */
    //创建小圆基准面
    // datum.createPlaneByDistance({
    //   planeId: datumId1,
    //   invertNormal: 0,
    //   paralDis: gearParams.teethWidth,
    //   reverse: 1,
    // }, "基准面2");
    // let axis2 = new Axis();
    // let x = -gearParams.teethWidth / Math.cos(gearParams.delta);
    // axis2.setPoint(new Point(x, 0, 0), new Point(x-1, 1 / Math.tan(gearParams.delta), 0));
    // datum.createPlaneByPlaneAngle({
    //   planeId: 8,
    //   additionalAxis: axis2,
    //   axisAngle: 90,
    // }, "基准面2");
    //通过点和法向创建基准面
    let xValue1 = gearParams.teethWidth / Math.cos(gearParams.delta);
    let yValue1 = 0;
    let planePnt = new Point(-xValue1, yValue1);//面上点
    let axis2 = new Axis();//法向
    let xValue2 = xValue1 - gearParams.teethWidth * Math.cos(gearParams.delta);
    let yValue2 = gearParams.teethWidth * Math.sin(gearParams.delta);
    axis2.setPoint(planePnt, new Point(-xValue2, yValue2));
    let res = await datum.createPlaneByPointNormalIncrement({
      planeAxis: axis2,
      planePnt: planePnt,
    }, "基准面2");
    let datumFeature2;
    let currentFeature = res?.data?.modelData?.currentFeature;
    if (currentFeature && currentFeature.length > 0) {
      let feature = {
        id: currentFeature[0]?.id,
        name: currentFeature[0]?.name,
      }
      datumFeature2 = feature;
    }
    //创建小圆的草图
    //获取基准面2的ID
    let entities2 = await this.getEntitiesByFeature(datumFeature2);
    if (entities2?.length === 0) {
      return;
    }
    let datumId2 = entities2?.[0].id;
    this.hideEntityIds.push(datumId2);
    let h = gearParams.rp / Math.sin(gearParams.delta);
    let ratio = (h - gearParams.teethWidth) / h;
    gearParams.ra = gearParams.ra2;
    gearParams.rb = gearParams.rb2;
    gearParams.rf = gearParams.rf2;
    gearParams.rp = gearParams.rp2;
    // gearParams.ra *= ratio;
    // gearParams.rb *= ratio;
    // gearParams.rf *= ratio;
    // gearParams.rp *= ratio;
    // gearParams.h2 = (this.rf - 0.8 * this.h) * Math.cos(this.delta);
    gearParams.teethFilterR *= ratio;
    gearParams.helixAngle = 0;
    let distance2 = await this.createGearSketch("草图2", datumId2, gearParams);
    // 做倒圆角
    // await this.createFilletCorner(distance2, "草图2");

    //移动旋转草图位置
    await this.moveRotateElements("草图2", gearParams, true);
  }

  getLineRevolvePoint(lineDir,linePoint,point,angle){
    //角度转换为弧度
    angle = angle * Math.PI / 180;

    //根据轴和角度设计旋转矩阵
    let rotateMatrix = new THREE.Matrix4();
    rotateMatrix.makeRotationAxis(lineDir,angle);

    //将旋转点进行位移到原点为基准的位置
    let directionToPoint = new THREE.Vector3().subVectors(point,linePoint);
    //应用旋转矩阵进行旋转
    directionToPoint.applyMatrix4(rotateMatrix);

    //旋转后的点加上基准
    let rotatedPoint = directionToPoint.add(linePoint);
    return rotatedPoint;
  }
  //创建齿的草图
  async createGearSketch(sketchName, datumId, gearParams) {
    const sketch = this.command.sketch;
    sketch.createSketch({sketchName: sketchName, datumId: datumId});
    const angle = Math.PI / 3;
    const hAngle = gearParams.helixAngle / 2;

    /*
    绘制两侧渐开线：
    获取右侧渐开线与分度圆交点 Q
    通过齿距弦长计算 OQ 与对称轴之间的角度 θ，得到 Q 在对称轴上的投影点 M
    以 OM 为对称轴，得到左侧渐开线
    */
    let ratio = gearParams.rf / gearParams.ra;
    const QPoint = this.getIntersectionPointInInvolute(0, angle, gearParams.rb, gearParams.rp);
    let theta = Math.PI / (2 * gearParams.teethNumber) * Math.cos(gearParams.delta);
    if (gearParams.rf2 / gearParams.rf === 1) {
      theta *= 1.2;
    }

    let mX = QPoint.x * Math.cos(theta) - QPoint.y * Math.sin(theta);
    const mY = QPoint.x * Math.sin(theta) + QPoint.y * Math.cos(theta);
    // mX = mX * Math.cos(gearParams.delta);
    const MPoint = new THREE.Vector3(mX, mY);
    const OPoint = new THREE.Vector3(0, 0);

    // let rpPnt = this.getPoint(symmetryPoint(new THREE.Vector3(QPoint.x, QPoint.y), OPoint, MPoint));
    // sketch.createSketchLine({
    //   startPoint: new Point(0, 0),
    //   endPoint: new Point(QPoint.x, QPoint.y),
    // });
    // sketch.createSketchLine({
    //   startPoint: new Point(0, 0),
    //   endPoint: rpPnt,
    // });
    // sketch.createSketchLine({
    //   startPoint: new Point(0, 0),
    //   endPoint: new Point(0, gearParams.rp),
    // });
    // sketch.createSketchLine({
    //   startPoint: new Point(0, 0),
    //   endPoint: new Point(0, gearParams.ra),
    // });
    // 齿根圆关键点与其对称点
    let pointF = this.getPoint({x: 0, y: gearParams.rf});
    let pointFS = this.getPoint(symmetryPoint(new THREE.Vector3(0, gearParams.rf), OPoint, MPoint));

    // 齿顶圆与右侧渐开线的交点P, 交点处的角度值, 以及其对称点PS
    let intersectionPointAndAngle = this.getIntersectionPointAndAngleInInvolute(0, angle, gearParams.rb, gearParams.ra);
    let intersectionPointAngle = intersectionPointAndAngle.angle;
    let pointP = this.getPoint({x: intersectionPointAndAngle.x, y: intersectionPointAndAngle.y});
    let pointPS = this.getPoint(symmetryPoint(new THREE.Vector3(intersectionPointAndAngle.x, intersectionPointAndAngle.y), OPoint, MPoint));  // 对称点
    // sketch.createSketchLine({
    //   startPoint: new Point(0, 0),
    //   endPoint: new Point(pointP.x, pointP.y),
    // });


    // 绘制渐开线
    const involuteRightPoints = [];
    const involuteLeftPoints = [];
    const increment = 0.05;
    if (gearParams.rb > gearParams.rf) {
      for (let i = 0; i < intersectionPointAngle; i += increment) {
        const x = gearParams.rb * (Math.sin(i) - i * Math.cos(i));
        const y = gearParams.rb * (Math.cos(i) + i * Math.sin(i));
        involuteRightPoints.push(this.getPoint({x, y}));
        const symPoint = symmetryPoint(new THREE.Vector3(x, y), OPoint, MPoint);  // 对称点
        involuteLeftPoints.push(this.getPoint(symPoint));
      }
      // 添加与齿顶圆的交点
      involuteRightPoints.push(pointP);
      involuteLeftPoints.push(pointPS);
      // 渐开线最后一个点为与齿顶圆交点外一点的点
      let lastPointAngle = intersectionPointAngle + 0.03 + hAngle;
      const x = gearParams.rb * (Math.sin(lastPointAngle) - lastPointAngle * Math.cos(lastPointAngle));
      const y = gearParams.rb * (Math.cos(lastPointAngle) + lastPointAngle * Math.sin(lastPointAngle));
      involuteRightPoints.push(this.getPoint({x, y}));
      const symPoint = symmetryPoint(new THREE.Vector3(x, y), OPoint, MPoint);  // 对称点
      involuteLeftPoints.push(this.getPoint(symPoint));
    } else {  // 齿根圆半径大于基圆半径，以齿根圆与渐开线交点为起点，绘制渐开线
      const interPoint = this.getIntersectionPointInInvolute(0, angle, gearParams.rb, gearParams.rf);
      pointF = this.getPoint(interPoint);
      pointFS = this.getPoint(symmetryPoint(new THREE.Vector3(interPoint.x, interPoint.y), OPoint, MPoint));
      involuteRightPoints.push(pointF);
      involuteLeftPoints.push(pointFS);
      for (let i = 0; i < angle; i += increment) {
        const x = gearParams.rb * (Math.sin(i) - i * Math.cos(i));
        const y = gearParams.rb * (Math.cos(i) + i * Math.sin(i));
        if (Math.sqrt(x * x + y * y) > gearParams.rf) {
          involuteRightPoints.push(this.getPoint({x, y}));
          const symPoint = symmetryPoint(new THREE.Vector3(x, y), OPoint, MPoint);
          involuteLeftPoints.push(this.getPoint(symPoint));
        }
      }
      // 渐开线最后一个点为与齿顶圆交点外一点的点
      let lastPointAngle = angle + 0.03 + hAngle;
      const x = gearParams.rb * (Math.sin(lastPointAngle) - lastPointAngle * Math.cos(lastPointAngle));
      const y = gearParams.rb * (Math.cos(lastPointAngle) + lastPointAngle * Math.sin(lastPointAngle));
      involuteRightPoints.push(this.getPoint({x, y}));
      const symPoint = symmetryPoint(new THREE.Vector3(x, y), OPoint, MPoint);  // 对称点
      involuteLeftPoints.push(this.getPoint(symPoint));
    }

    sketch.createIntpCurve({pickPoints: involuteRightPoints});
    sketch.createIntpCurve({pickPoints: involuteLeftPoints});

    // 两侧渐开线上顶点连线
    sketch.createArcByCenter({
      centerPoint: new Point(0, 0),
      startPoint: new Point(involuteRightPoints[involuteLeftPoints.length - 1].x, involuteRightPoints[involuteLeftPoints.length - 1].y),
      endPoint: new Point(involuteLeftPoints[involuteLeftPoints.length - 1].x, involuteLeftPoints[involuteLeftPoints.length - 1].y)
    });

    // 齿根圆
    sketch.createArcByCenter({
      centerPoint: new Point(0, 0),
      startPoint: pointF,
      endPoint: pointFS
    });

    const delta = Math.sqrt((involuteRightPoints[0].x - pointF.x) * (involuteRightPoints[0].x - pointF.x) +
      (involuteRightPoints[0].y - pointF.y) * (involuteRightPoints[0].y - pointF.y));
    // if (delta > gearParams.teethFilterR) {
      // 渐开线与圆角连线
      sketch.createSketchLine({
        startPoint: new Point(involuteRightPoints[0].x, involuteRightPoints[0].y),
        endPoint: pointF
      });
      sketch.createSketchLine({
        startPoint: new Point(involuteLeftPoints[0].x, involuteLeftPoints[0].y),
        endPoint: pointFS
      });
    // }
    sketch.exitSketch();
    await this.command.executeIncrementCommand(this.command.commandScript);
    this.command.clearCommand();

    return delta;
  }
  async createFilletCorner(rho, featureName = '草图2')
  {
    let sketch = this.command.sketch;
    if (this.query) {
      let retElements = await this.query.getElementsByFeatureNames([featureName]);
      if (retElements?.elements?.length === 0 || retElements.elements.length < 7) {
        return;
      }
      let curveId1, curveId21, curveId22;
      let tempElement;
      let element1 = retElements.elements[3];//齿根圆弧
      if (element1.params.type === 12) {
        curveId1 = element1.id;
      }
      let element2 = retElements.elements[4];//齿根和渐开线的连线
      if (element2.params.type === 10) {
        curveId21 = element2.id;
      }
      let element3 = retElements.elements[5];//齿根和渐开线的连线
      if (element3.params.type === 10) {
        curveId22 = element3.id;
      }
      if (!curveId1 || !curveId21 || !curveId22) {
        return;
      }
      sketch.editSketch({sketchName: featureName});
      sketch.createFilletCurve({curveId1: curveId1, curveId2: curveId21, radius: rho, type1: 2, type2: 2});
      sketch.createFilletCurve({curveId1: curveId1, curveId2: curveId22, radius: rho, type1: 2, type2: 2});
      sketch.exitEditSketch({sketchName: featureName});
      await this.command.executeIncrementCommand(this.command.commandScript);
      this.command.clearCommand();
    }
  }
  //移动图元
  async moveRotateElements(sketchName, gearParams, isMove = false) {
    let sketch = this.command.sketch;
    let sketchFeature = await this.query.getEntitiesByFeatureNames([sketchName]);
    if (sketchFeature?.data?.entities?.length === 0){
      return;
    }
    let sketchEntity = sketchFeature?.data?.entities[0];
    sketchCoordinateSystem.setMatrix(sketchEntity.matrix);

    let retElements = await this.query.getElementsByFeatureNames([sketchName]);
    if (retElements?.data?.elements?.length === 0) {
      return;
    }
    let elementIds = [];
    let allElementObj = new THREE.Object3D();
    retElements?.data.elements.forEach(element => {
      if (element.type != ElementType.SKETCHREGION) {
        elementIds.push(element.id);
      }
    });
    //旋转一个角度
    let angle = -180 / (2 * gearParams.teethNumber) / 2;
    sketch.editSketch({sketchName: sketchName});
    sketch.rotateElements({elementIds: elementIds, centerPoint: new Point(0, 0), angle: angle});
    sketch.exitEditSketch({sketchName: sketchName});
    await this.command.executeIncrementCommand(this.command.commandScript);
    this.command.clearCommand();
    if (gearParams.helixDirection != 0) {
      sketch.editSketch({sketchName: sketchName});
      sketch.rotateElements({elementIds: elementIds, centerPoint: new Point(0, 0), angle: gearParams.helixAngle});
      sketch.exitEditSketch({sketchName: sketchName});
      await this.command.executeIncrementCommand(this.command.commandScript);
      this.command.clearCommand();
    }
    if (isMove) {
      let startPnt = new THREE.Box3().expandByObject(allElementObj.clone()).getCenter(new THREE.Vector3());
      let pointX = 0;
      let pointY = gearParams.teethWidth * Math.tan(gearParams.delta);
      let offsetPnt = new THREE.Vector3(pointX, pointY, 0);
      let endPnt = this.fromXoy(offsetPnt.add(this.toXoy(startPnt.clone())));
      // let moveDis = gearParams.teethWidth / Math.cos(gearParams.delta) * Math.cos(90 - gearParams.delta);
      sketch.editSketch({sketchName: sketchName});
      sketch.moveElements({
        elementIds: elementIds,
        startPnt: new Point(startPnt.x, startPnt.y, startPnt.z),
        endPnt: new Point(endPnt.x, endPnt.y, endPnt.z)
      });
      sketch.exitEditSketch({sketchName: sketchName});
      await this.command.executeIncrementCommand(this.command.commandScript);
      this.command.clearCommand();
    }
  }
  //!<从当前草图平面转换到XOY平面
  toXoy(point) {
    if (Number.isFinite(point)) {
      return point / sketchCoordinateSystem.getScale();
    }
    let newMat = new THREE.Matrix4();
    newMat.copy(sketchCoordinateSystem.getMatrix()).invert();
    return point.clone().applyMatrix4(newMat);
  }

  //!< 从XOY平面转换到当前草图平面
  fromXoy(point) {
    if (Number.isFinite(point)) {
      return point * sketchCoordinateSystem.getScale();
    }
    return point.clone().applyMatrix4(sketchCoordinateSystem.getMatrix());
  }

  /**
   * 创建旋转凸台及圆锥体
   * @param gearParams
   * @param cb
   * @returns
   */
  async createCones(gearParams) {
    //旋转凸台做的比齿大，为了后面做布尔减运算
    //凸台草图
    const sketch = this.command.sketch;
    sketch.createSketch({sketchName: "凸台草图", datumId: 8});
    sketch.createSketchLine({
      startPoint: new Point(-gearParams.x1, gearParams.y1),
      endPoint: new Point(-gearParams.x2, gearParams.y2)
    });
    sketch.createSketchLine({
      startPoint: new Point(-gearParams.x2, gearParams.y2),
      endPoint: new Point(-gearParams.x3, gearParams.y3)
    });
    sketch.createSketchLine({
      startPoint: new Point(-gearParams.x3, gearParams.y3),
      endPoint: new Point(-gearParams.x4, gearParams.y4)
    });
    sketch.createSketchLine({
      startPoint: new Point(-gearParams.x4, gearParams.y4),
      endPoint: new Point(-gearParams.x5, gearParams.y5)
    });
    sketch.createSketchLine({
      startPoint: new Point(-gearParams.x5, gearParams.y5),
      endPoint: new Point(-gearParams.x6, gearParams.y6)
    });
    sketch.createSketchLine({
      startPoint: new Point(-gearParams.x6, gearParams.y6),
      endPoint: new Point(-gearParams.x1, gearParams.y1)
    });
    sketch.exitSketch();
    let bossSketchFeature = await this.executeIncrementCommand();
    //根据草图创建旋转凸台
    let entities = await this.getEntitiesByFeature(bossSketchFeature);
    if (entities?.length === 0) {
      return;
    }
    let solid = this.command.solid;
    let axis = new Axis();
    axis.setPoint(new Point(0, 0, 0), new Point(1, 0, 0));
    await solid.revolveIncrement({
      sketch: entities[0].id,
      axis: axis,
      angle1: 360,
      toSurface1: 0,
      revolveType2: -1,
    }, "旋转凸台");
    // const solid = this.command.solid;
    // 上下各创建一个圆锥体
    let dir = new Direction();
    dir.setPoint(new Point(0, 0, 0), new Point(1, 0, 0));//方向x轴
    let center1 = new Point(-gearParams.circleCenter1, 0, 0);
    let center2 = new Point(-gearParams.x5, 0, 0);
    //第一个圆锥体
    await solid.createConeIncrement({
      center: center1, direction: dir,
      radius: gearParams.r2, height: gearParams.height1, minorRadius: gearParams.r1
    }, "圆锥体1");
    //第二个圆锥体
    await solid.createConeIncrement({
      center: center2, direction: dir,
      radius: gearParams.y5, height: gearParams.height2, minorRadius: gearParams.r3
    }, "圆锥体2");
  }
  // 放样创建柱斜齿轮切除体
  async createLoft(featureName1 = '草图1', featureName2 = '草图2') {
    let solid = this.command.solid;
    let sketch1 = await this.query.getEntitiesByFeatureNames([featureName1]);
    if (sketch1?.data?.entities?.length === 0) {
      return;
    }
    let sketch2 = await this.query.getEntitiesByFeatureNames([featureName2]);
    if (sketch2?.data?.entities?.length === 0) {
      return;
    }
    let guideCurve = await this.query.getEntitiesByFeatureNames(["引导线"]);
    if (guideCurve?.data?.entities?.length === 0) {
      return;
    }
    let sketchArray = [sketch1?.data?.entities[0]?.id, sketch2?.data?.entities[0]?.id];
    let guidCurveId = guideCurve?.data?.entities[0]?.id;
    await solid.loftIncrement({
      sketchs: sketchArray,
      hasGuideCurve: 1,
      guideCurves: [guidCurveId],
    }, '放样凸台');
    this.hideEntityIds.push(guidCurveId);
  }
  //创建圆周阵列
  async createCircularPattern(insNum) {
    // 创建放样凸台圆周阵列
    let entityObject = await this.query.getEntitiesByFeatureNames(["放样凸台"]);
    if (entityObject?.data?.entities?.length === 0) {
      return;
    }
    const axis = new Axis();
    axis.setPoint(new Point(0, 0, 0), new Point(1, 0, 0));
    // axis.setPoint(new Point(0, 0, 0), new Point(0, 0, 10));
    let res = await this.command.solid.circularPatternIncrement({
      baseType: 0, body: entityObject?.data?.entities[0]?.id, axis: axis, angle1: 360, instanceNum1: insNum,
    }, '圆周阵列');
    let currentFeature = res?.data?.modelData?.currentFeature;
    if (currentFeature && currentFeature.length > 0) {
      let feature = {
        id: currentFeature[0]?.id,
        name: currentFeature[0]?.name,
      }
      return feature;
    }
  }

  /**
   * 创建引导线
   */
  async createGuideLine() {
    let sketch1 = await this.query.getElementsByFeatureNames(['草图1']);
    let sketch2 = await this.query.getElementsByFeatureNames(['草图2']);
    let elements1 = sketch1?.data?.elements;
    let elements2 = sketch2?.data?.elements;
    if (!elements1 || !elements2) {
      return;
    }
    let elementsLength1 = elements1.length;
    let elementsLength2 = elements2.length;
    if (elementsLength1 === 0 || elementsLength2 === 0) {
      return;
    }
    let points = [];
    for(let i = 0; i < elementsLength1; i++){
      if (elements1[i]?.params?.type === 10) {
        let endPnt = elements1[i].params.startPoint;
        let pnt = this.infinitesimal(new Point(endPnt[0], endPnt[1], endPnt[2]));
        points.push(pnt);
        break;
      }
    }
    for(let i = 0; i < elementsLength2; i++){
      if (elements2[i]?.params?.type === 10) {
        let endPnt = elements2[i].params.startPoint;
        let pnt = this.infinitesimal(new Point(endPnt[0], endPnt[1], endPnt[2]));
        points.push(pnt);
        break;
      }
    }
    await this.command.curve.createCurveByInterpolationPointsIncrement({pickPnts: points}, '引导线');
  }

  //将无限小的数转换成0
  infinitesimal(pnt) {
    if (Math.abs(pnt.x) < 0.0001) {
      pnt.x = 0;
    }
    if (Math.abs(pnt.y) < 0.0001) {
      pnt.y = 0;
    }
    if (Math.abs(pnt.z) < 0.0001) {
      pnt.z = 0;
    }
    return pnt;
  }
  //布尔减运算
  async boolSub(circularPatternFeature) {
    if (!circularPatternFeature) {
      return;
    }
    //工具
    let res1 = await this.query.getEntitiesByFeatureNames(['放样凸台']);
    let res2 = await this.toolQuery.getEntitiesByFeatureId(circularPatternFeature.id);
    let res3 = await this.query.getEntitiesByFeatureNames(['圆锥体2']);
    //目标
    let res4 = await this.query.getEntitiesByFeatureNames(['旋转凸台']);
    let loftEntities = res1?.data?.entities;
    let circularPatternEntities = res2?.data?.entities;
    let coneEntities = res3?.data?.entities;
    let rotateEntities = res4?.data?.entities;
    if (!loftEntities || !circularPatternEntities ||
      !coneEntities || !rotateEntities) {
      return;
    }
    if (loftEntities.length === 0 || circularPatternEntities.length === 0 || coneEntities.length === 0 || rotateEntities.length === 0) {
      return;
    }
    let cutSolidIds = [];
    cutSolidIds.push(loftEntities[0].id);
    circularPatternEntities.forEach(entity => {
      cutSolidIds.push(entity.id);
    });
    cutSolidIds.push(coneEntities[0].id);
    let targetSolidId = rotateEntities[0].id;
    await this.command.solid.booleanSubtractIncrement({
      entityBs: cutSolidIds,
      entityA: targetSolidId,
      keep: 0
    }, '布尔减');
  }
}

const gearDesignCommand = new GearDesignCommand();
export {gearDesignCommand};
